﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using BrainTechLLC;
using System.Collections.ObjectModel;

namespace BrainTechLLC.Silverlight.ClientApplication
{
    public partial class FindGameThings : UserControl
    {
        public event EventHandler<ObjectEventArgs<LocationInt>> RequestGoLocation;
        public event EventHandler<ObjectEventArgs<LocationInt>> RequestEditGameLocation;

        public event EventHandler CloseWindow;
        public event EventHandler<ObjectEventArgsNonRef<long>> RequestEditID;

        public FindGameThings()
        {
            InitializeComponent();
        }

        public void OnRequestEditID(object sender, ObjectEventArgsNonRef<long> e)
        {
            if (RequestEditID != null)
                RequestEditID(sender, e);
        }

        private void typeFilter_TypeChanged(object sender, ObjectEventArgs<Type> e)
        {
            thingList.FilterType = e.obj;
            var things = DoSearch(searchCriteria.GetCurrentSearchCritera());
            searchCriteria.ReflectIDsInTextbox(things);
            thingList.ThingList = things;
        }

        private void WindowContainer_CloseWindow(object sender, EventArgs e)
        {
            if (CloseWindow != null)
                CloseWindow(this, e);
            else
                wc2.Visibility = Visibility.Collapsed;
        }

        public ObservableCollection<object> DoSearch(SearchCriteria criteria)
        {
            ObservableCollection<object> things = null;

            if (criteria.IDs != null)
            {
                things = Everything.Find<IGameThing>(criteria.IDs).Cast<object>().ToObservable();
            }

            if (criteria.Type != null)
            {
                if (things == null)
                    things = Everything.FindAllThingsOfType<IGameThing>().Cast<object>().ToObservable();

                things.RemoveWhere((o) => !criteria.Type.IsAssignableFrom(o.GetType()));
            }

            if (!string.IsNullOrEmpty(criteria.Keywords))
            {
                if (things == null)
                    things = Everything.FindAllThingsOfType<IGameThing>().Cast<object>().ToObservable();

                things.RemoveWhere((o) =>
                    {
                        BaseClass bc = o as BaseClass;
                        string best;
                        float f = bc.KeywordMatchStrength(criteria.Keywords, out best);
                        return (f < 0.44f);
                    });
            }

            return things == null ? new ObservableCollection<object>() : things;
        }

        private void InputSearchCriteria_SearchRequested(object sender, ObjectEventArgs<SearchCriteria> e)
        {
            var things = DoSearch(e.obj);
            searchCriteria.ReflectIDsInTextbox(things);
            thingList.ThingList = things;
        }

        private void thingList_RequestEditID(object sender, ObjectEventArgsNonRef<long> e)
        {
            OnRequestEditID(sender, e);
        }

        private void thingList_RequestGoLocation(object sender, ObjectEventArgs<LocationInt> e)
        {
            OnRequestGoToLocation(sender, e);
        }

        public void OnRequestGoToLocation(object sender, ObjectEventArgs<LocationInt> e)
        {
            if (RequestGoLocation != null)
                RequestGoLocation(this, e);
        }

        public void OnRequestEditGameLocation(object sender, ObjectEventArgs<LocationInt> e)
        {
            if (RequestEditGameLocation != null)
                RequestEditGameLocation(this, e);
        }

        private void thingList_RequestEditGameLocation(object sender, ObjectEventArgs<LocationInt> e)
        {
            OnRequestEditGameLocation(sender, e);
        }
    }

    public class SearchCriteria
    {
        public string Keywords { get; set; }
        public Type Type { get; set; }
        public List<long> IDs { get; set; }
    }

}
